/**
 * Copyright (C) 2007 Transmute Technologies. All rights reserved.
 * ===============================================================
 * Component Desc : 
 * Major :
 * Minor :
 * @author Naveen Kumar
 * Mail : unaveenkumar@gmail.com
 * Created on : Jan 14, 2007
 *
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 *
 * Modified by : Jan 14, 2007
 * Revision number : 0.5
 *
 * Revision History
 * ----------------
 * 
 */
package org.transmute.dao;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * <p/> Hold the actual connection and other related details.
 * </p>
 * 
 * @author Naveen Kumar
 */
class ConnectionWrapper extends AConnection {

	/**
	 * <p>
	 * Constructor to intialize the ConnectionWrapper for the specified
	 * connection object.
	 * </p>
	 * 
	 * @param connection -
	 *            Connection object.
	 * @param assigned -
	 *            Boolean flag to specify whether the connection is in
	 *            connection pool or not.
	 */
	ConnectionWrapper(Connection connection, ConnectionDetails conn,
			boolean assigned) {
		this.connection = connection;
		this.assigned = assigned;
		timeOutMilles = conn.getTimeOut();
		lastAccessed = System.currentTimeMillis();
		key = conn.formKey();
	}

	/**
	 * Method to change the connection state to assigned state
	 */
	void assignConnection() {
		synchronized(this){
			assigned = true;
		}
	}

	/* (non-Javadoc)
	 * @see java.sql.Connection#close()
	 * 
	 */
	public void close() throws SQLException {
		synchronized(this) {		
			if (connection != null) {
				connection.close();
				connection = null;
				assigned = false;
			}
		}
	}

	/**
	 * <p>
	 * Method to close the connection.
	 * </p>
	 */
	public void closeConnection() {
		try {
			if (connection != null) {
				synchronized(this){
					connection.close();
					connection = null;
				}
			}
		} catch (Exception exp) {
		}
	}
	
	/**
	 * <p>
	 * Method that returns the connection object.
	 * </p>
	 * 
	 * @return Connection - Conneciton object.
	 */
	Connection getConnection() {
//		synchronized (this) {
//			updateAccessTime();
//			assigned = true;
//		}
		// This will be always called only to check if connection exists or its null
		// during the closeConnection of the connectionPool
		// Neednot do the 
		return connection == null ? null : connection;
	}

	/**
	 * <p>
	 * Method to check whether the connection is assigned to the pool or not.
	 * </p>
	 * 
	 * @return boolean - Returns true if the connection is assigned .
	 */
	boolean isAssigned() {
		return assigned;
	}

	/**
	 * <p>
	 * Method to check whether the connection is closed or not.
	 * </p>
	 * 
	 * @return boolean - Returns true if the connection is closed.
	 */
	public boolean isClosed() {
		try {
			if (connection != null) {
				return connection.isClosed();
			}
		} catch (SQLException sql) {
		}
		return true;
	}

	/**
	 * asks if the engine has timed out
	 * 
	 * @return boolean - whether the last accessed is more that timeOutMilles
	 *         older.
	 */
	boolean isTimeOut() {
		// if the compare is negative or equal to zero.. then time out is true
		long currentTime = System.currentTimeMillis();
		return ((currentTime - lastAccessed) > timeOutMilles);
	}

	/**
	 * <p>
	 * Method to get
	 * </p>
	 * 
	 * @return
	 */
	/*
	 * public boolean isClosed() throws SQLException{ updateAccessTime(); return
	 * this.connection.isClosed(); }
	 */

	/**
	 * <p>
	 * Method to check whether the connection is valid or not.
	 * </p>
	 * 
	 * @return boolean - Returns true if the connection is valid.
	 */
	 boolean isValid() {
		boolean flag = false;
		java.sql.DatabaseMetaData dmd = null;
		try {
			if ((connection != null) && !connection.isClosed()) {
				dmd = connection.getMetaData();
				dmd.getUserName();
				flag = true;
			}
		} catch (Exception exp) {
			System.out.println("Error Raised in " + toString() + exp);
		}
		return flag;
	}

	/**
	 * <p>
	 * Method to close the connection if the connection has not been used for a
	 * while.
	 * </p>
	 * 
	 * @return void.
	 */
	void releaseConnection() {
		synchronized(this) {
			updateAccessTime();
			assigned = false;
		}
	}
}
